﻿using AutoBlogger.Properties;
using HtmlAgilityPack;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AutoBlogger.DB
{
    internal class BlogModel
    {
        [BsonId]
        public uint Id { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
        public bool IsPosted { get; set; }

        HtmlNode html;

        //internal BlogModel() { }

        internal BlogModel(string documentStr)
        {
            HtmlDocument htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(documentStr);
            HtmlNode contentNode = htmlDoc.DocumentNode.SelectSingleNode("//div[@class='entry']");
            if (contentNode == null)
            {
                return;
            }

            var hs = contentNode.SelectNodes(".//span[@class='youdao-hiddenspan']");
            if (hs != null)
            {
                foreach (var item in hs)
                {
                    item.ParentNode.RemoveChild(item);
                }
            }
            html = HtmlNode.CreateNode("<div></div>");

            this.Title = contentNode.SelectSingleNode("div[1]/h1[1]/a[1]").Attributes["title"].Value;

            HtmlNode imgNode = getImgNode(contentNode);
            html.AppendChild(imgNode);

            HtmlNode summaryNode = getSummaryNode(contentNode);
            html.AppendChild(summaryNode);

            HtmlNode tableNode = getTableNode(contentNode);
            html.AppendChild(tableNode);

            HtmlNode detailNode = getDetailNode(contentNode);
            html.AppendChild(detailNode);

            var tipNode = getTipNode(contentNode);
            html.AppendChild(tipNode);

            this.Content = html.OuterHtml;
            this.Id = Settings.Default.CurrentNum;
        }

        private static HtmlNode getTipNode(HtmlNode contentNode)
        {
            var node = contentNode.Elements("div").ElementAt(2);

            foreach (var n in node.DescendantsAndSelf())
            {
                while (n.HasAttributes)
                {
                    n.Attributes[0].Remove();
                }
            }
            return node;
        }

        private static HtmlNode getDetailNode(HtmlNode contentNode)
        {
            var node = contentNode.SelectSingleNode("div[@class='lrlrecipestep']");
            foreach (var n in node.DescendantsAndSelf())
            {
                if (n.Name == "img")
                {
                    continue;
                }
                while (n.HasAttributes)
                {
                    n.Attributes[0].Remove();
                }
            }
            return node;
        }

        private HtmlNode getTableNode(HtmlNode contentNode)
        {
            HtmlNode node = HtmlNode.CreateNode("<table><caption></caption></table>");
            var tableNode = (from ds in contentNode.Descendants("div")
                             where (ds.Attributes["class"] != null && ds.Attributes["class"].Value == "lrlrecipedo")
                             select ds).FirstOrDefault();

            node.ChildNodes[0].InnerHtml = tableNode.SelectSingleNode("h4/span").Element("#text").InnerText;

            IEnumerable<HtmlNode> liNodes = tableNode.Descendants("li");
            if (liNodes != null)
            {
                for (int i = 0; i < liNodes.Count(); i++)
                {
                    HtmlNode tr = HtmlNode.CreateNode("<tr><td></td><td></td></tr>");
                    HtmlNode li = liNodes.ElementAt(i);

                    if (li.ChildNodes.Count == 0)
                    {
                        continue;
                    }

                    HtmlNode a = li.Element("a");
                    if (a != null)
                    {
                        if (a.Element("span") != null)
                        {
                            tr.ChildNodes[1].InnerHtml = a.Element("span").InnerHtml;
                        }
                        else
                        {
                            tr.ChildNodes[1].InnerHtml = a.Element("#text").InnerHtml;
                        }
                        tr.ChildNodes[0].InnerHtml = li.SelectSingleNode("span").Element("#text").InnerHtml;
                    }
                    else
                    {
                        IEnumerable<HtmlNode> spans = li.Elements("span");
                        tr.ChildNodes[0].InnerHtml = spans.ElementAt(0).InnerHtml;
                        var n = spans.ElementAt(1);
                        var n1 = n.Element("span");
                        if (n1 == null)
                        {
                            tr.ChildNodes[1].InnerHtml = n.InnerText;
                        }
                        else
                        {
                            tr.ChildNodes[1].InnerHtml = n1.InnerText;
                        }
                    }

                    node.AppendChild(tr);
                }
            }
            return node;
        }

        private HtmlNode getSummaryNode(HtmlNode contentNode)
        {
            var summaryNode = (from ds in contentNode.Descendants("div")
                               where (ds.Attributes["class"] != null && ds.Attributes["class"].Value == "infob")
                               select ds).Single();
            //HtmlNode summaryNode = contentNode.SelectSingleNode("//div[@class='infob']");
            HtmlNode node = HtmlNode.CreateNode("<span></span>");
            StringBuilder sb = new StringBuilder();
            var spans = summaryNode.SelectNodes("span");

            if (spans != null)
            {
                foreach (var item in spans)
                {
                    sb.Append(item.InnerText);
                }
            }

            node.InnerHtml = sb.ToString();
            return node;
        }

        private HtmlNode getImgNode(HtmlNode contentNode)
        {
            HtmlNode imgNode = contentNode.SelectSingleNode("div[1]/div[2]");
            imgNode.Attributes.RemoveAll();
            imgNode.ChildNodes[0].Attributes.Remove("style");
            return imgNode;
        }
    }
}
